/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.facebook.presto.plugin.neo4j;

import com.facebook.presto.spi.function.Description;
import com.facebook.presto.spi.function.ScalarFunction;
import com.facebook.presto.spi.function.SqlType;
import com.facebook.presto.spi.type.StandardTypes;

import static java.lang.Math.asin;
import static java.lang.Math.cos;
import static java.lang.Math.pow;
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;
import static java.lang.Math.toRadians;

//@AggregationFunction("geo_shortest_distance")
@ScalarFunction("geo_distance")
@Description("Calculate geographic distance")
public class Neo4jGeoUtil
{
    private Neo4jGeoUtil()
    {
    }

    @SqlType(StandardTypes.DOUBLE)
    public static double geoDistance(@SqlType(StandardTypes.DOUBLE) double targetLatitude,
            @SqlType(StandardTypes.DOUBLE) double targetLongitude,
            @SqlType(StandardTypes.DOUBLE) double compareLatitude,
            @SqlType(StandardTypes.DOUBLE) double compareLongitude)
    {
        return calDistance(targetLatitude, targetLongitude, compareLatitude, compareLongitude);
    }

    private static double calDistance(double lat1, double lon1, double lat2, double lon2)
    {
        return 2 * asin(sqrt(pow(sin((toRadians(lat1) - toRadians(lat2)) / 2), 2)
                + cos(toRadians(lat1)) * cos(toRadians(lat2)) * pow(sin((toRadians(lon1) - toRadians(lon2)) / 2), 2))) * 6378.137;
    }
}
